// file: x86/arch/task/tss.c
// autor: jiangxinpeng
// time: 2021.1.1
// copyright: (C) 2020-2050 by jiangxinpeng,All right are reserved.

#include <arch/tss.h>
#include <lib/string.h>
#include <arch/page.h>
#include <arch/segment.h>
#include <arch/descript.h>
#include <arch/x86.h>
#include <arch/task.h>
#include <arch/mp.h>
#include <arch/config.h>
#include <os/task.h>

tss_t tss0; // tss only for BSP processor

void TssInit()
{
    // set kernel stack
    tss0.ss0 = SEG_SEL_KERNEL_STACK;
    tss0.esp0 = MEM_KERNEL_STACK_BOTTOM;
    tss0.io_map = DISIOMAP;
    LoadTR(SEG_SEL_TSS);

    KPrint("[tss] kernel status statck init done. ss0: %x esp0: %x\n", tss0.ss0, tss0.esp0);
}

tss_t *GetCurrentTSS()
{
#ifdef ENABLE_SMP
    return (tss_t *)CurProcessor->init_data.tss;
#else
    return &tss0;
#endif
}

void UpdateTSS(address_t task)
{
#ifdef ENABLE_SMP
    tss_t *tss = (tss_t *)CurProcessor->init_data.tss;
#else
    tss_t *tss = &tss0;
#endif
    // update tss stack top to user kernel stack top
    tss->esp0 = task + TASK_KERNEL_STACK_SIZE;
}

void DumpTss(tss_t *tss)
{
    KPrint("---task state stack----\n");
    KPrint("ss0 %p esp %p io_map %x\n", tss->ss0, tss->esp0, tss->io_map);
}